﻿using System;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using PortalWeb.Common;
using PortalWeb.Core.Entity;
using PortalWeb.Dao;
using PortalWeb.Service;
using PortalWeb.Core;
using PortalWeb.Core.IManager;
using Quick.Common.Components;

namespace PortalWeb.Filter
{

    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        /// <summary>
        /// 能够访问的角色
        /// </summary>
        public new string Roles { get; set; }

        private string[] RolesArray
        {
            get { return Roles.Split(','); }

        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }
            if (!httpContext.User.Identity.IsAuthenticated)
            {
                //非验证用户直接失败
                return false;
            }
            if (Roles == null)
            {
                //不需要角色直接成功
                return true;
            }
            if (Roles.Length == 0)
            {
                //不需要角色直接成功
                return true;
            }
            if (RolesArray.Any(httpContext.User.IsInRole))
            {
                //用户包含其中一个角色，返回成功
                return true;
            }
            return base.AuthorizeCore(httpContext);
        }


        public override async void OnAuthorization(AuthorizationContext filterContext)
        {
            string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
            string actionName = filterContext.ActionDescriptor.ActionName;
            string area = string.Empty;
            if (filterContext.RouteData.DataTokens["area"] != null)
            {
                area = filterContext.RouteData.DataTokens["area"].ToString();
            }
            var roles = await GetRoles.GetActionRolesAsync(actionName, controllerName, area);
            if (!string.IsNullOrWhiteSpace(roles))
            {
                this.Roles = roles;
            }
            base.OnAuthorization(filterContext);
        }



        public class GetRoles
        { 
            public static async Task<string> GetActionRolesAsync(string action, string controller, string area)
            {
                string cachekey = string.Format("RolsCache~/{0}/{1}/{2}", area, controller, action);
                object rolesObject = CacheHelper.Get(cachekey);
                if (rolesObject == null)
                {
                    //todo:以后使用IOC框架取得
                    var sfm = ObjectContainer.Resolve<IFunctionManager>();

                    string actionUrl = string.Format("/{0}/{1}/{2}", area, controller, action).ToLower();
                    var function = await sfm.GetByUrlAsync(actionUrl);

                    string roles = "";
                    if (function != null)
                    {
                        foreach (var role in function.Roles)
                        {
                            roles += role.Name + ",";
                        }
                    }
                    CacheHelper.Insert(cachekey, roles);
                    return roles;
                }
                else
                {
                    return rolesObject as string;
                }
            }

           
        }
    }
}